/*
 * Detector.cpp
 *
 *  Created on: Apr 20, 2010
 *      Author: Soheil Damangir
 */

#include <iostream>
#include "image.h"
#include "log.h"

#include "Detector.h"
#include "../Util/Conf.h"
#include "../Util/ImageLog.h"

using kthrobot::Log;
namespace Group5{

Detector::Detector(std::istream&is): classifier(is)
{
  clr = new bool*[Constants::get().IMG_Y];
  clr[0] = new bool[Constants::get().IMG_X*Constants::get().IMG_Y];
  for (int i = 1; i < Constants::get().IMG_Y; i++)
    clr[i] = clr[0] + i*Constants::get().IMG_X;
}

void Detector::detect(kthrobot::Image&image, DetectionResults&results, const char* what="Detector")
{
  int total_pixs = Constants::get().IMG_X*Constants::get().IMG_Y;

  uint8_t*pixels = image.buffer();
  int x=0,y=0;
  int min_x = image.w(), max_x = 0, min_y = image.h(), max_y = 0;
  int DX = 0;
  for (int i = 0;i<total_pixs;i++)
  {
    x = i%Constants::get().IMG_X;
    y = i/Constants::get().IMG_X;
    if (x==0)
    {
      DX = 0;
    }
    bool tmp = classifier.classify((int*)pixels);

    clr[y][x] = tmp;

    if (clr[y][x]){
      DX++;

      if(x > max_x)
        max_x = x;
      else if(x < min_x)
        min_x = x;

      if(y > max_y)
        max_y = y;
      else if(y < min_y)
        min_y = y;

    }else{
      if (DX < x && DX < Constants::get().MORPH_DX)
      {
        for (int xx = x-DX;xx < x; xx++)
          clr[y][xx]=false;
      }
      DX = 0;

    }
    pixels += image.num_components();
  }
  results.size = 0;
  results.x = 0;
  results.y = 0;

  _max_x = min_x, _max_y = min_y, _min_x = min_x, _min_y = min_y;
  for (y = min_y;y <= max_y; y++)
  {
    for (x = min_x;x <= max_x; x++)
    {
      clr[y][x] = clr[y][x]&&(clr[y==0?y:y-1][x]||clr[y==image.h()-1?y:y+1][x]);
      if (clr[y][x])
      {
        results.size++;
        results.x += x;
        results.y += y;
        if(x > _max_x)
          _max_x = x;
        else if(x < _min_x)
          _min_x = x;

        if(y > _max_y)
          _max_y = y;
        else if(y < _min_y)
          _min_y = y;
      }
    }
  }

  results.x /= results.size;
  results.y /= results.size;
  results.detected = results.size > Constants::get().MIN_BALL_SIZE;
  results.h = _max_y - _min_y;
  results.w = _max_x - _min_x;
  ImageLog::get().LogBinary(clr,image.w(),image.h(),what);
}
Detector::~Detector()
{
  delete[] clr[0];
  delete[] clr;
}

}
